package org.ericquan8.trojanclient.util;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.util.Random;

import com.mortennobel.imagescaling.AdvancedResizeOp;
import com.mortennobel.imagescaling.ResampleOp;

import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.imageio.ImageIO;

import org.ericquan8.trojanclient.Key;

public class ImageUtil {

    private static GraphicsDevice device =
            GraphicsEnvironment.getLocalGraphicsEnvironment().
            getDefaultScreenDevice();
    private static DisplayMode mode = device.getDisplayMode();
    private static Dimension size = new Dimension(mode.getWidth(), mode.getHeight());
    private static final Rectangle rectangle =
            new Rectangle(new Point(0, 0), size);

    private ImageUtil() {
    }

    public static BufferedImage scaleImage(BufferedImage image,
            int formatWidth, int formatHeight) {

        int width = image.getWidth();
        int height = image.getHeight();

        int imageWidth = width;
        int imageHeight = height;
        int changeToWidth = 0;
        int changeToHeight = 0;
        if (imageWidth > 0 && imageHeight > 0) {
            if (imageWidth / (double) imageHeight >= formatWidth / (double) formatHeight) {
                if (imageWidth > formatWidth) {
                    changeToWidth = formatWidth;
                    changeToHeight = (imageHeight * changeToWidth) / imageWidth;
                } else {
                    changeToWidth = imageWidth;
                    changeToHeight = imageHeight;
                }
            } else {
                if (imageHeight > formatHeight) {
                    changeToHeight = formatHeight;
                    changeToWidth = (imageWidth * changeToHeight) / imageHeight;
                } else {
                    changeToWidth = imageWidth;
                    changeToHeight = imageHeight;
                }
            }
        }

        if (width <= changeToWidth && height <= changeToHeight) {
            return image;
        }

        ResampleOp resampleOp = new ResampleOp(changeToWidth, changeToHeight);
        resampleOp.setUnsharpenMask(AdvancedResizeOp.UnsharpenMask.None);
        return resampleOp.filter(image, null);
    }

    public static BufferedImage scaleImage(BufferedImage image, int size, boolean isWidth) {

        int width = image.getWidth();
        int height = image.getHeight();

        if (width <= size) {
            return image;
        }

        ResampleOp resampleOp = null;

        if (isWidth) {
            resampleOp = new ResampleOp(size, size * height / width);
        } else {
            resampleOp = new ResampleOp(size * width / height, size);
        }

        resampleOp.setUnsharpenMask(AdvancedResizeOp.UnsharpenMask.None);
        return resampleOp.filter(image, null);
    }

    public static Color getRandColor(int fc, int bc) {
        Random random = new Random();
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

    public BufferedImage getImage(String path) throws IOException {
        BufferedImage image = ImageIO.read(new File(path));
        return image;
    }

    public void copyImage(String source, String targetFileName) throws IOException {
        BufferedImage sourceImage = ImageIO.read(new File(source));
        ImageIO.write(sourceImage, "JPEG", new File(targetFileName));
    }
    public static Robot robot = null;

    public static Image getWindowsImage() {
        if (robot == null) {
            try {
                robot = new Robot();
            } catch (AWTException ex) {
                Logger.getLogger(ImageUtil.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        Image image = null;
        BufferedImage screenshot = null;
        screenshot = robot.createScreenCapture(rectangle);
        BufferedImage zipImage = scaleImage(screenshot, Key.WIDTH, Key.HEIGHT);
        image = screenshot.getScaledInstance(zipImage.getWidth(),
                zipImage.getHeight(), Image.SCALE_DEFAULT);
        return image;
    }

    public static BufferedImage getWindowsImageBuffer() {
        if (robot == null) {
            try {
                robot = new Robot();
            } catch (AWTException ex) {
                Logger.getLogger(ImageUtil.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        Image image = null;
        BufferedImage screenshot = null;
        screenshot = robot.createScreenCapture(rectangle);
        BufferedImage zipImage = scaleImage(screenshot, Key.WIDTH, Key.HEIGHT);
        return zipImage;
    }

    public static byte[] getCompressedImage(BufferedImage image) {

        byte[] imageData = null;

        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(image, "jpg", baos);
            imageData = baos.toByteArray();
        } catch (IOException ex) {
        	ex.printStackTrace();
            imageData = null;
        }

        return imageData;
    }
}
